package com.base.lib.base

import android.content.ContentValues
import android.content.Context
import android.content.Intent
import android.content.pm.ActivityInfo
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.provider.MediaStore
import android.util.Log
import android.view.View
import android.view.WindowManager
import android.view.inputmethod.InputMethodManager
import butterknife.ButterKnife
import com.amap.api.location.AMapLocation
import com.amap.api.location.AMapLocationClient
import com.amap.api.location.AMapLocationClientOption
import com.amap.api.location.AMapLocationListener
import com.base.lib.R
import com.base.lib.utils.Constant
import com.base.lib.utils.UploadHelper
import com.base.lib.utils.eventbus.EventBusHelper
import com.base.lib.utils.eventbus.EventBusMessage
import com.base.lib.utils.jpush.JPushSetUitl
import com.base.lib.view.SnackbarUtil
import cxy.com.validate.Validate
import me.imid.swipebacklayout.lib.SwipeBackLayout
import me.imid.swipebacklayout.lib.app.SwipeBackActivity
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import pub.devrel.easypermissions.EasyPermissions
import java.io.File
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.*

/**
 * @author harisucici
 * @date 07.03
 */
abstract class BaseActivity<V, T : BasePresenter<V>?> : SwipeBackActivity(), BaseView,
    EasyPermissions.PermissionCallbacks {
    @JvmField
    var mCamareFile: File? = null
    var jPushSetUitl: JPushSetUitl? = null
    protected var mVideoCameraFile: File? = null
    protected var locationClient: AMapLocationClient? = null
    protected var locationOption: AMapLocationClientOption? = null
    @JvmField
    protected var mPresenter: T? = null
    // 定位监听
    var locationListener = AMapLocationListener { location: AMapLocation? ->
        if (null != location) {
            if (location.longitude > 1) {
                stopLocation()
                EventBusHelper.sendEventBusMsg(EventBusHelper.LOCATION_SUCCESS)
                Log.i(TAG, "定位服务运行成功并拿到了数据---loc=== " + location.address)
            } else {
                Log.i(TAG, "定位服务运行成功，数据异常---loc为0=== $location")
            }
        } else {
            Log.i(TAG, "定位服务启动失败---loc is null===")
        }
    }
    private var progressDialog: ProgressDialog? = null
    private lateinit var mSwipeBackLayout: SwipeBackLayout
    abstract fun initPresenter(): T
    override fun onCreate(savedInstanceState: Bundle?) {
        mPresenter = initPresenter()
        if (progressDialog == null) {
            progressDialog = ProgressDialog()
        }
        window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
        super.onCreate(savedInstanceState)
        mSwipeBackLayout = swipeBackLayout
        mSwipeBackLayout.setEdgeTrackingEnabled(SwipeBackLayout.EDGE_LEFT)
//        ActivityTracker.getInstance().onCreate(this)
        jPushSetUitl = JPushSetUitl.getPushSetUitl(this)
        setContentView(setViewId())
        ButterKnife.bind(this)
        Validate.reg(this)
        initView()
        initData()
        //强制横竖
        requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
    }
    override fun getActivityContext(): Context? {
        return this
    }
    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this)
    }

    override fun onPermissionsGranted(requestCode: Int, perms: List<String>) {
        showShortToast("权限请求成功!")
    }

    override fun onPermissionsDenied(requestCode: Int, perms: List<String>) {
        showShortToast("权限请求失败!")
    }

    public override fun onStart() {
        super.onStart()
        Log.i("BaseActivity", "onStart")
    }

    public override fun onResume() {
        super.onResume()
        mPresenter?.attachView(this as V)
        if (!EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this)
        }
        doOnResume()
        Log.i("BaseActivity", "onResume")
    }

    public override fun onPause() {
        super.onPause()
        Log.i("BaseActivity", "onPause")
    }

    public override fun onDestroy() {
        super.onDestroy()
        mPresenter?.detachView()
        Validate.unreg(this)
        EventBus.getDefault().unregister(this)
//        ActivityTracker.getInstance().onDestory(this)
        destroyLocation()
        doOnDestroy()
        Log.i("BaseActivity", "onDestroy")
    }

    public override fun onSaveInstanceState(savedInstanceState: Bundle) {
        super.onSaveInstanceState(savedInstanceState)
        doOnSaveInstanceState(savedInstanceState)
        Log.i("BaseActivity", "onSaveInstanceState")
    }

    protected abstract fun setViewId(): Int
    protected abstract fun initView()
    protected abstract fun initData()
    protected abstract fun doOnDestroy()
    protected abstract fun doOnResume()
    protected abstract fun doOnSaveInstanceState(savedInstanceState: Bundle?)
    @Subscribe
    fun onEventMainThread(eventBusMessage: EventBusMessage) {
        if (eventBusMessage.code == Constant.SESSION_TIMEOUT) { //            showShortToast("登录状态失效，请重新登录");
//            SpHelper.getInstance().clearAll();
//            Utils.getInstance().startActivity(this, LoginActivity.class, null, false);
//            ActivityTracker.getInstance().finishAll();
        }
    }

    override fun showLoadingDialog() { //        showLoadingDialog(null, "请等待");
        if (progressDialog!!.tag == null) {
            progressDialog!!.show(supportFragmentManager, "progress")
        }
    }

    override fun dismissLoadingDialog() {
        if (progressDialog != null) {
            progressDialog!!.dismiss()
        }
    }

//    override fun getActContext(): Context {
//        return this
//    }

    fun showShortToast(message: String) {
        val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm?.hideSoftInputFromWindow(window.decorView.windowToken, 0)
        SnackbarUtil.showBarShortTime(findViewById(android.R.id.content), message, SnackbarUtil.INFO)
    }

    fun showShortToast(message: String, type: Int) {
        val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm?.hideSoftInputFromWindow(window.decorView.windowToken, 0)
        SnackbarUtil.showBarShortTime(findViewById(android.R.id.content), message, type)
    }

    protected fun showLongToast(message: String, info: String?, listener: View.OnClickListener, type: Int) {
        val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm?.hideSoftInputFromWindow(window.decorView.windowToken, 0)
        SnackbarUtil.showBarLongTime(findViewById(android.R.id.content), message, type, info, listener)
    }

    fun chooseLocImage() {
        val intent = Intent(Intent.ACTION_GET_CONTENT)
        intent.type = "image/*"
        startActivityForResult(intent, Constant.REQUEST_CODE_IMAGE)
    }

    fun chooseLocCamera(path: String) {
        val dir = File(Environment.getExternalStorageDirectory(), "Jh3502/$path")
        if (!dir.exists()) {
            dir.mkdirs()
        }
        val df = SimpleDateFormat("yyyyMMddHHmmss") //设置日期格式在android中，创建文件时，文件名中不能包含“：”冒号
        val filename = df.format(Date())
        mCamareFile = File(dir, "$filename.png")
        if (!mCamareFile!!.exists()) {
            try {
                mCamareFile!!.createNewFile()
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
        selectImageFromCamera(Constant.REQUEST_CODE_CAMERA, mCamareFile)
    }

    fun selectImageFromCamera(requestCode: Int, saveImage: File?) {
        var saveImage = saveImage
        if (saveImage == null) {
            Log.i(TAG, "Image file parameter is null.")
            saveImage = File(Environment.getExternalStorageDirectory(), System.currentTimeMillis().toString() + ".png")
        }
        val currentapiVersion = Build.VERSION.SDK_INT
        Log.i(TAG, "---currentapiVersion===$currentapiVersion")
        val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
        if (currentapiVersion < Build.VERSION_CODES.N) {
            intent.action = MediaStore.ACTION_IMAGE_CAPTURE
            intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(saveImage))
            intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1)
        } else {
            if (saveImage.exists()) {
                try {
                    saveImage.createNewFile()
                } catch (e: IOException) {
                    e.printStackTrace()
                }
            }
            val contentValues = ContentValues()
            contentValues.put(MediaStore.Images.Media.DATA, saveImage.absolutePath)
            val uri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
            intent.putExtra(MediaStore.EXTRA_OUTPUT, uri)
        }
        startActivityForResult(intent, requestCode)
    }

    protected fun chooseLocVideo() {
        val intent = Intent(Intent.ACTION_GET_CONTENT)
        intent.type = "video/*"
        startActivityForResult(intent, Constant.REQUEST_CODE_VIDEO)
    }

    val imageFromCamera: Unit
        get() {
            mCamareFile = UploadHelper.getInstance().getCameraSaveFile(this, System.currentTimeMillis())
            UploadHelper.getInstance().selectImageFromCamera(this, Constant.REQUEST_CODE_CAMERA, mCamareFile)
        }

    fun saveImageFromCamera(path: String) {
        val dir = File(Environment.getExternalStorageDirectory(), "Jh3502/$path")
        if (!dir.exists()) {
            dir.mkdirs()
        }
        val df = SimpleDateFormat("yyyyMMddHHmmss") //设置日期格式在android中，创建文件时，文件名中不能包含“：”冒号
        val filename = df.format(Date())
        mCamareFile = File(dir, "$filename.png")
        if (!mCamareFile!!.exists()) {
            try {
                mCamareFile!!.createNewFile()
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
        UploadHelper.getInstance().selectImageFromCamera(this, Constant.REQUEST_CODE_CAMERA, mCamareFile)
    }

    val videoFromCamera: Unit
        get() {
            mVideoCameraFile = UploadHelper.getInstance().getCameraSaveVideoFile(this, System.currentTimeMillis())
            UploadHelper.getInstance().selectVideoFromCamera(this, Constant.REQUEST_CODE_VIDEO_CAMERA, mVideoCameraFile)
        }

    override fun requestFailure(t: Throwable?) {
        if (t.toString().contains(Constant.TIMEOUT_EXCEPTION)) {
            showShortToast(getString(R.string.servicer_no_response))
        }
    }

//    fun showInteractionDialog(msg: String?, okListener: DialogInterface.OnClickListener?) {
//        showInteractionDialog(msg, true, "确认", "取消", okListener, DialogInterface.OnClickListener { dialog: DialogInterface, which: Int -> dialog.dismiss() })
//    }
//    fun showInteractionDialog(msg: String?, cancelable: Boolean, ok: String?, no: String?,
//                              okListener: DialogInterface.OnClickListener?,
//                              noListener: DialogInterface.OnClickListener?) {
//        val builder = CustomDialog.Builder(this)
//        builder.setMessage(msg)
//        builder.setPositiveButton(ok, okListener)
//        if (!TextUtils.isEmpty(no)) {
//            builder.setNegativeButton(no, noListener)
//        }
//        val dialog = builder.create()
//        dialog.setCancelable(cancelable)
//        dialog.show()
//    }

    protected fun checkPermission(vararg permissions: String?): Boolean {
        return if (permissions.size == 0) {
            EasyPermissions.hasPermissions(this, *Constant.PERMISSIONS)
        } else {
            EasyPermissions.hasPermissions(this, *permissions)
        }
    }

    protected fun requestPermission(vararg permissions: String?) {
        if (permissions.size == 0) {
            EasyPermissions.requestPermissions(this,
                    getString(R.string.permission_rationale),
                    Constant.REQUEST_PERMISSION_CODE,
                    *Constant.PERMISSIONS)
        } else {
            EasyPermissions.requestPermissions(this,
                    getString(R.string.permission_rationale),
                    Constant.REQUEST_PERMISSION_CODE,
                    *permissions)
        }
    }

    /**
     * 初始化定位
     *
     * @author hongming.wang
     * @since 2.8.0
     */
    protected fun initLocation(listener: AMapLocationListener?) { //初始化client
        locationClient = AMapLocationClient(this.applicationContext)
        locationOption = defaultOption
        //设置定位参数
        locationClient!!.setLocationOption(locationOption)
        // 设置定位监听
        if (listener == null) {
            locationClient!!.setLocationListener(locationListener)
        } else {
            locationClient!!.setLocationListener(listener)
        }
        startLocation()
    }//可选，设置定位模式，可选的模式有高精度、仅设备、仅网络。默认为高精度模式
    //可选，设置是否gps优先，只在高精度模式下有效。默认关闭
    //可选，设置网络请求超时时间。默认为30秒。在仅设备模式下无效
    //可选，设置定位间隔。默认为2秒
    //可选，设置是否返回逆地理地址信息。默认是true
    //可选，设置是否单次定位。默认是false
    //可选，设置是否等待wifi刷新，默认为false.如果设置为true,会自动变为单次定位，持续定位时不要使用
    //可选， 设置网络请求的协议。可选HTTP或者HTTPS。默认为HTTP
    //可选，设置是否使用传感器。默认是false
    //可选，设置是否开启wifi扫描。默认为true，如果设置为false会同时停止主动刷新，停止以后完全依赖于系统刷新，定位位置可能存在误差
    //可选，设置是否使用缓存定位，默认为true

    /**
     * 默认的定位参数
     *
     * @author hongming.wang
     * @since 2.8.0
     */
    private val defaultOption: AMapLocationClientOption
        private get() {
            val mOption = AMapLocationClientOption()
            //可选，设置定位模式，可选的模式有高精度、仅设备、仅网络。默认为高精度模式
            mOption.locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy
            //可选，设置是否gps优先，只在高精度模式下有效。默认关闭
            mOption.isGpsFirst = true
            //可选，设置网络请求超时时间。默认为30秒。在仅设备模式下无效
            mOption.httpTimeOut = 30000
            //可选，设置定位间隔。默认为2秒
            mOption.interval = 3000
            //可选，设置是否返回逆地理地址信息。默认是true
            mOption.isNeedAddress = true
            //可选，设置是否单次定位。默认是false
            mOption.isOnceLocation = false
            //可选，设置是否等待wifi刷新，默认为false.如果设置为true,会自动变为单次定位，持续定位时不要使用
            mOption.isOnceLocationLatest = false
            //可选， 设置网络请求的协议。可选HTTP或者HTTPS。默认为HTTP
            AMapLocationClientOption.setLocationProtocol(AMapLocationClientOption.AMapLocationProtocol.HTTPS)
            //可选，设置是否使用传感器。默认是false
            mOption.isSensorEnable = false
            //可选，设置是否开启wifi扫描。默认为true，如果设置为false会同时停止主动刷新，停止以后完全依赖于系统刷新，定位位置可能存在误差
            mOption.isWifiScan = true
            //可选，设置是否使用缓存定位，默认为true
            mOption.isLocationCacheEnable = true
            return mOption
        }

    /**
     * 开始定位
     *
     * @author hongming.wang
     * @since 2.8.0
     */
    protected fun startLocation() {
        Log.i(TAG, "---startLocation===")
        // 设置定位参数
        locationClient!!.setLocationOption(locationOption)
        // 启动定位
        locationClient!!.startLocation()
    }

    /**
     * 停止定位
     *
     * @author hongming.wang
     * @since 2.8.0
     */
    protected fun stopLocation() { // 停止定位
        locationClient!!.stopLocation()
    }

    /**
     * 销毁定位
     *
     * @author hongming.wang
     * @since 2.8.0
     */
    private fun destroyLocation() {
        if (null != locationClient) {
            /**
             * 如果AMapLocationClient是在当前Activity实例化的，
             * 在Activity的onDestroy中一定要执行AMapLocationClient的onDestroy
             */
            locationClient!!.onDestroy()
            locationClient = null
            locationOption = null
        }
    }

    companion object {
        private const val TAG = "BaseActivity"
    }
}